package xin.marcher.module.seller.concurrent;

import java.util.concurrent.Semaphore;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 *
 */
public class PreheatCacheThreadPool {

    private final Semaphore semaphore;

    private final ThreadPoolExecutor threadPoolExecutor;

    public PreheatCacheThreadPool(int permits) {
        // 如果超过了20个任务同时要运行，会通过semaphore信号量阻塞
        semaphore = new Semaphore(permits);

        // 这里设置核心线程数为0，是因为缓存预热的任务是一次性执行，所以没有比要保留核心线程
        // 等线程工作完毕，线程就全部退出即可
        threadPoolExecutor = new ThreadPoolExecutor(
                0,
                permits * 2,
                60,
                TimeUnit.SECONDS,
                new SynchronousQueue<>()
        );
    }

    public void execute(Runnable task) {
        // 超过了20个同步任务就阻塞住，不让它执行太多
        semaphore.acquireUninterruptibly();

        threadPoolExecutor.submit(() -> {
            try {
                task.run();
            } finally {
                semaphore.release();
            }
        });
    }
}